package com.draemoncode.weixindb.mvc;

import com.draemoncode.weixindb.constant.AutoMessageConstant;
import com.draemoncode.weixindb.constant.MessagePackageTypeConstant;
import com.draemoncode.weixindb.constant.ValueConstant;
import com.draemoncode.weixindb.conventer.BusiConventer;
import com.draemoncode.weixindb.domain.*;
import com.draemoncode.weixindb.mvc.exception.BusiException;
import com.draemoncode.weixindb.mvc.vo.Action200ResponseVO;
import com.draemoncode.weixindb.mvc.vo.MessageTemplateVO;
import com.draemoncode.weixindb.repository.*;
import com.draemoncode.weixindb.server.*;
import com.draemoncode.weixindb.service.MemberService;
import com.draemoncode.weixindb.util.JSONUtil;
import com.draemoncode.weixindb.util.JvmUtil;
import com.draemoncode.weixindb.util.ValueUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import javax.transaction.Transactional;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@Slf4j
@Transactional
public class ActionController {

    @Autowired(required = false)
    private List<IAction> actionList = new ArrayList<>();

    @Autowired
    private List<IEvent> eventList = new ArrayList<>();

    @Autowired
    private B_CMessagePackageRepository b_cMessagePackageRepository;

    @Autowired
    private B_AutoMessage_TemplateRepository b_autoMessage_templateRepository;

    @Autowired
    private B_Calculate_CodeRepository b_calculate_codeRepository;

    @Autowired
    private B_Calculate_EnvRepository b_calculate_envRepository;

    @Autowired
    private B_MemberRepository b_memberRepository;

    @Autowired
    private MemberService memberService;

    @RequestMapping(value = "/action/{action}", method = RequestMethod.POST)
    @Transactional
    public Action200ResponseVO action(@PathVariable("action") String action){
        Action200ResponseVO result = new Action200ResponseVO();
        for (IAction iAction : actionList) {
            if(iAction.shoudProcess(action)){
                Object busiResult = iAction.busiExec();
                Object uiResult = iAction.uiExec(busiResult);
                CMessagePackage response = iAction.buildResponse(busiResult, uiResult);
                if(response != null){
                    CSession.send(response);
                }
                result.setValue(uiResult);
            }
        }
        return result;
    }

    @RequestMapping(value = "/event", method = RequestMethod.POST)
    @Transactional
    public void event(@RequestBody EventValue event){
        try {
//            CMessagePackage parseMsg = JSONUtil.parse(event.getEvent(), CMessagePackage.class);
//            Map values = JSONUtil.parse(event.getEvent(), HashMap.class);
//            parseMsg.setMsg(values);
//            B_CMessagePackage b_cMessagePackage = CMessagePackageConventer.toB_CMessagePackage(parseMsg);
            B_CMessagePackage b_cMessagePackage = new B_CMessagePackage();
            b_cMessagePackage.setMsg(event.getEvent());
            B_CMessagePackage save = b_cMessagePackageRepository.save(b_cMessagePackage);
            B_CMessagePackage one = b_cMessagePackageRepository.findOne(save.getId());
            System.out.println(one.getMsg());
//            boolean haveExec = false;
//            for (IEvent iEvent : eventList) {
//                if(iEvent.shoudProcess(parseMsg)){
//                    Object busiResult = iEvent.busiExec(parseMsg);
//                    Object uiResult = iEvent.uiExec(parseMsg, busiResult);
//                    CMessagePackage cMessagePackage = iEvent.buildResponse(parseMsg, busiResult, uiResult);
//                    if(cMessagePackage != null){
//                        CSession.send(cMessagePackage);
//                    }
//                    haveExec = true;
//                }
//            }
//            if(!haveExec){
//                log.error("丢包未处理: " + event);
//            }
        }catch (BusiException e) {
            Map<String, Object> map = new HashMap<>();
            map.put("msg", e.getMessage());
            CMessagePackage cMessagePackage = new CMessagePackage();
            cMessagePackage.setType(e.getCode());
            cMessagePackage.setMsg(map);
            CSession.send(cMessagePackage);
            log.error(e.getMessage(), e);
        } catch (Exception e) {
            Map<String, Object> map = new HashMap<>();
            map.put("exception", JvmUtil.printHTMLStackTrace(e, "\n"));
            CMessagePackage cMessagePackage = new CMessagePackage();
            cMessagePackage.setType(MessagePackageTypeConstant.RESPONSE_ERROR);
            cMessagePackage.setMsg(map);
            CSession.send(cMessagePackage);
            log.error(e.getMessage(), e);
        }
    }

    @RequestMapping(value = "/message/settingsSave", method = RequestMethod.POST)
    public MessageTemplateVO message_settingsSave(@RequestParam("shangZhuangMessage") String shangZhuangMessage, @RequestParam("calculateMessage") String calculateMessage){
        B_AutoMessage_Template zhuangTemplate = b_autoMessage_templateRepository.findByFlag(AutoMessageConstant.ZHUANG_JIA_TEMPLATE);
        if(zhuangTemplate != null){
            zhuangTemplate.setTemplate(shangZhuangMessage);
            b_autoMessage_templateRepository.save(zhuangTemplate);
        }else{
            B_AutoMessage_Template b_autoMessage_template = new B_AutoMessage_Template();
            b_autoMessage_template.setFlag(AutoMessageConstant.ZHUANG_JIA_TEMPLATE);
            b_autoMessage_template.setName("庄家消息模板");
            b_autoMessage_template.setTemplate(shangZhuangMessage);
            b_autoMessage_templateRepository.save(b_autoMessage_template);
        }
        B_AutoMessage_Template calulateTemplate = b_autoMessage_templateRepository.findByFlag(AutoMessageConstant.CALULATE_TEMPLATE);
        if(calulateTemplate != null){
            calulateTemplate.setTemplate(calculateMessage);
            b_autoMessage_templateRepository.save(calulateTemplate);
        }else{
            B_AutoMessage_Template b_autoMessage_template = new B_AutoMessage_Template();
            b_autoMessage_template.setFlag(AutoMessageConstant.CALULATE_TEMPLATE);
            b_autoMessage_template.setName("结算消息模板");
            b_autoMessage_template.setTemplate(calculateMessage);
            b_autoMessage_templateRepository.save(b_autoMessage_template);
        }
        List<B_AutoMessage_Template> list = b_autoMessage_templateRepository.findAll();
        return BusiConventer.toMessageTemplateVO(list);
    }

    @RequestMapping(value = "/caculatecode/save", method = RequestMethod.POST)
    public Action200ResponseVO caculatecodeSave(@RequestParam("groupName") String groupName, @RequestParam("name") String name, @RequestParam("code") String code){
        B_Calculate_Code b_calculate_code = new B_Calculate_Code();
        b_calculate_code.setGroupName(groupName);
        b_calculate_code.setName(name);
        b_calculate_code.setCalculate_code(code);
        b_calculate_codeRepository.save(b_calculate_code);
        return new Action200ResponseVO();
    }

    @RequestMapping(value = "/caculatecode/enable", method = RequestMethod.POST)
    public Action200ResponseVO caculatecodeEnable(@RequestParam("id") Integer caculateId){
        b_calculate_codeRepository.disableAll();
        B_Calculate_Code one = b_calculate_codeRepository.findOne(caculateId);
        one.setEnable(ValueConstant.ENABLE);
        b_calculate_codeRepository.save(one);
        return new Action200ResponseVO();
    }

    @RequestMapping(value = "/caculateenv/save", method = RequestMethod.POST)
    public B_Calculate_Env caculateenvSave(@RequestParam("caculateId") Integer caculateId, @RequestParam("calculate_env_key") String calculate_env_key, @RequestParam("calculate_env_name") String calculate_env_name, @RequestParam("calculate_env_value") String calculate_env_value, @RequestParam(value = "isNewRecord", required = false) boolean isNewRecord, @RequestParam(value = "id", required = false) Integer id){
        if(isNewRecord){
            B_Calculate_Env check = b_calculate_envRepository.findByCalculateCodeAndKey(caculateId, calculate_env_key);
            if(check != null){
                throw new BusiException(HttpStatus.BAD_REQUEST.value(), "报存失败, 变量码不能重复:" + calculate_env_key);
            }
            B_Calculate_Env b_calculate_env = new B_Calculate_Env();
            b_calculate_env.setCalculate_code_id(caculateId);
            b_calculate_env.setCalculate_env_key(calculate_env_key);
            b_calculate_env.setCalculate_env_name(calculate_env_name);
            b_calculate_env.setCalculate_env_value(calculate_env_value);
            B_Calculate_Env save = b_calculate_envRepository.save(b_calculate_env);
            return save;
        }else{
            B_Calculate_Env check = b_calculate_envRepository.findByCalculateCodeAndKey(caculateId, calculate_env_key);
            if(check != null && !check.getId().equals(id)){
                throw new BusiException(HttpStatus.BAD_REQUEST.value(), "报存失败, 变量码不能重复:" + calculate_env_key);
            }
            B_Calculate_Env byCalculateCodeAndKey = b_calculate_envRepository.findOne(id);
            byCalculateCodeAndKey.setCalculate_env_key(calculate_env_key);
            byCalculateCodeAndKey.setCalculate_env_name(calculate_env_name);
            byCalculateCodeAndKey.setCalculate_env_value(calculate_env_value);
            B_Calculate_Env save = b_calculate_envRepository.save(byCalculateCodeAndKey);
            return save;
        }
    }

    @RequestMapping(value = "/caculateenv/delete")
    public Action200ResponseVO caculateenvDelete(@RequestParam(value = "id") Integer id){
        b_calculate_envRepository.delete(id);
        return new Action200ResponseVO();
    }

    @RequestMapping(value = "/caculateenv/change")
    public Action200ResponseVO caculateenvChange(@RequestParam(value = "change") String change){
        List<Map<String, Object>> values = JSONUtil.parse(change, ArrayList.class);
        for (Map<String, Object> map : values) {
            Integer id = ValueUtil.toInteger(map.get("id"));
            String value = ValueUtil.toString(map.get("value"));
            B_Calculate_Env one = b_calculate_envRepository.findOne(id);
            one.setCalculate_env_value(value);
            b_calculate_envRepository.save(one);
        }
        return new Action200ResponseVO();
    }

    @RequestMapping(value = "/members/shangfen")
    @Transactional
    public Action200ResponseVO membersShangfen(@RequestParam(value = "id") Integer id, @RequestParam(value = "value") BigDecimal value){
        B_Member one = b_memberRepository.findByIdForUpdate(id);
        memberService.changeAccountByChongZhi(one, value);
        return new Action200ResponseVO();
    }


}
